<html>
    <head>
        <title>组件：状态的内存</title>
    </head>
    <body>
        <script>
            // 组件： 状态的内存
                /*
                    作为交互的结果，组件通常需要更改屏幕上的内容。
                    在表单中输入应该更新输入字段，单击图片轮播上的 “下一个” 应该更改显示的图片，单击 “购买” 应该将产品放入购物车。
                    组件需要 “记住” 的东西：当前输入值，当前图片，购物车。在 React 中，这种特定于组件的内存称为状态。
                */


                    // 一、当常规变量功能不够时
                            /*
                                这是一个渲染雕塑图片的组件。
                                对它的期望是，单击"下一个" 按钮应显示下一个雕塑， 方式是将 index 改为1，然后改为2，以此类推。
                                但是，这样不行！
                            */
                                    import { sculptureList } from './data.js';

                                    export default function Gallery() {
                                        let index = 0;

                                        function handleClick() {
                                            index = index + 1;
                                        }

                                        let sculpture = sculptureList[index];
                                        return (
                                            <div>
                                                <button onClick={handleClick}>
                                                    Next
                                                </button>
                                                <h2>
                                                    <i>{sculpture.name} </i> 
                                                    by {sculpture.artist}
                                                </h2>
                                                <h3>  
                                                    ({index + 1} of {sculptureList.length})
                                                </h3>
                                                <img 
                                                    src={sculpture.url} 
                                                    alt={sculpture.alt}
                                                />
                                                <p>
                                                    {sculpture.description}
                                                </p>
                                            </div>
                                        );
                                    }
                            /*
                                虽然事件处理程序 handleClick 正在更新局部变量index .但是在两个因素的影响下它不会按照预期工作：
                                     1.当组件重新渲染时，index 会被重置为0.
                                            这是因为每次组件重新渲染时，React 都会丢弃之前的局部变量。

                                     2.对局部变量个更改，不会触发重新渲染。
                                            这是因为React没有意识到它需要用新数据重新渲染组件。

                                所以，要使用新数据更新组件，必须要满足两个条件：
                                     1、保留渲染之之间的数据。
                                     2、触发React 使用新数据进行重新渲染。

                                 useState 钩子提供了这两个条件：
                                    1、提供了用于保留渲染之间数据的状态变量。
                                    2、一个状态设置函数，用于更新状态变量，并触发React重新渲染组件。
                            */



                    // 二、添加状态变量

                             // 要添加状态变量，请在文件顶部从React导入 useState:

                                import {useState} from 'react';

                             // 然后用数组结构语法调用 useState，并将初始状态值作为参数传递给它

                                // 0 为状态变量的初始值   useSate钩子，会创建一个"状态变量"和它的"设置函数"，并放到数组里返回，然后通过"数组结构赋值"赋值给两个局部变量
                                const [index,setIndex]=useState(0); 

                             // eg: 改在上面的组件：
                                    import {useState} from 'react';
                                    import { sculptureList } from './data.js';

                                    export default function Gallery(){
                                        const [index,setIndex] = useState(0);

                                        function handleClick(){
                                            setIndex(index+1);
                                        }

                                        let sculpture = sculptureList[index];
                                        return(
                                            <div>
                                                <button onClick={handleClick}>
                                                    Next
                                                </button>
                                                <h2>
                                                    <i>{sculpture.name} </i> 
                                                    by {sculpture.artist}
                                                </h2>
                                                <h3>  
                                                    ({index + 1} of {sculptureList.length})
                                                </h3>
                                                <img 
                                                    src={sculpture.url} 
                                                    alt={sculpture.alt}
                                                />
                                                <p>
                                                    {sculpture.description}
                                                </p>
                                            </div>
                                        );
                                    }


                    // 三、认识你的第一个钩子
                                /*
                                    在React中，useState 以及任何其他 "use"开头的函数都称为 Hook.
                                    钩子是特殊函数，只有在React是渲染时才可用。它们可以让你接入不同的React特性。
                                    状态，只是其中的一个特性。
                                */
                                /*
                                    注意：
                                        Hooks(以use开头的函数)只能在组件的顶层调用，或者 你自己的钩子 你不能在条件、循环或其他嵌套函数内调用钩子；
                                        钩子是函数，但将它们视为关于组件需求的无条件声明会很有帮助。你在组件顶部的 “use” React 特性类似于你在文件顶部的 “导入” 模块。
                                */
       
                    // 四、 useState 的剖析

                                /*
                                    当你调用 useState时，其实你是在告诉React你想让你的组件记住一些什么东西。
                                        eg;
                                            const [index,setIndex] = useState(0);
                                        在这里，你希望React记住组件的index
                                */

                                /*
                                    useState 的唯一参数是状态变量的初始值。

                                    每次你的组件渲染时，useState 都会为你提供一个包含两个值的数组：

                                                    状态变量 (index) 以及你存储的值。

                                                    状态设置函数（setIndex），可以更新状态变量并触发 React 再次渲染组件。
                                */

                    // 五、为组件提供多个状态变量
                                /*
                                    你可以在一个组件中拥有任意数量的状态变量。
                                    如果状态变量不相关，那么拥有多个状态变量是个好主意。
                                    但是，如果你发现江场一起更改两个变量，则将它们合并为一个状态可能会更容易。

                                    eg：  如果你有一个包含许多字段的表单，则使用一个值为对象的状态变量比每个字段一个状态的方法更方便。
                                */


                    // 六、状态是"隔离的" 和"私有的"

                                /*
                                    状态对于屏幕上的组件实例是局部的。
                                    换句话说，如果你渲染同一个组件两次，每个实例都将具有"完全隔离的状态"！更改一其中一个实例的状态不会影响另一个实例。
                                */

                                /*
                                    还要注意 父组件不"知道"子关于子组件的任何状态信息，甚至不知道子组件有任何状态信息。
                                    与属性不同，状态对于声明它的组件来说是完全"私有的"。父组件无法更改它。
                                */
                    
        </script>
    </body>
</html>